package com.jay.lang.clazz;

public class ThrowableCls {
	
	
	public class DebugRunnable implements Runnable {

		private final Exception creationTime;
		private final Runnable delegate;

		public DebugRunnable(Runnable runner) {
			this.creationTime = new Exception("Debug Exception Creation");
			this.delegate = runner;
			// Drop this line from the creationTime trace..
			StackTraceElement[] trace = creationTime.getStackTrace();
			StackTraceElement[] newTrace = new StackTraceElement[trace.length - 1];
			System.arraycopy(trace, 1, newTrace, 0, newTrace.length);
			creationTime.setStackTrace(newTrace);
		}

		public final void run() {
			try {
				delegate.run();
			} catch (Throwable t) {
				if (t.getCause() == null) {
					t.initCause(creationTime);
				} else {
					// If it already had a cause, all we can do is manipulate
					// the StackTraceElement[]
					StackTraceElement[] trace = t.getStackTrace();
					StackTraceElement[] createdTrace = creationTime
							.getStackTrace();
					StackTraceElement[] combinedTrace = new StackTraceElement[trace.length
							+ createdTrace.length];
					System.arraycopy(trace, 0, combinedTrace, 0, trace.length);
					System.arraycopy(createdTrace, 0, combinedTrace,
							trace.length, createdTrace.length);
					t.setStackTrace(combinedTrace);
				}

				if (t instanceof Error)
					throw (Error) t;
				else if (t instanceof RuntimeException)
					throw (RuntimeException) t;
				else
					throw new RuntimeException(t);
			}
		}

	}
}
